<?php
namespace gnomephp\input;
/**
 * 
 * Abstract for filtering array of data.
 * 
 * @author peec
 *
 */
abstract class InputAbstract{
	/**
	 * 
	 * Instance of HTML purifier object.
	 * Only one instance the purifier should be needed.
	 * @var \HTMLPurifier
	 */
	static public $purifier = null;
	
	/**
	 * Keeps an array of the filtered data.
	 * @var array
	 */
	public $data=array();

	/**
	 * Object of config values.
	 * @var \HTMLPurifier_Config
	 */
	public $purifierConfig=null;

	/**
	 * If this had a full post check, don't filter again.
	 * @var bool
	 */
	private $fullpostCheck=false;

	/**
	 * Array of the source data from the raw input. Unfiltered source data.
	 * @var array
	 */
	private $sourceData=array();
	
	
	/**
	 * Source data can come from input arrays, forexample: $_POST, $_GET, $_COOKIE and so on.
	 * 
	 * @param array $sourceData
	 */
	public function __construct($sourceData){

		require_once GNOME_FW_PATH . DIRECTORY_SEPARATOR . 'libs' . DIRECTORY_SEPARATOR . 'htmlpurifier' . DIRECTORY_SEPARATOR . 'HTMLPurifier.standalone.php';

		$this->purifierConfig = \HTMLPurifier_Config::createDefault();
		 
		if (InputAbstract::$purifier===null)InputAbstract::$purifier = new \HTMLPurifier($this->purifierConfig);

		$this->sourceData = $sourceData;
	}
	

	

	/**
	 * 
	 * Gets the whole $_POST array or a specific key.
	 * You may define a closure funciton to configure the specific rules for the get.
	 * 
	 * Can be done like:
	 * $this->data->get('test', function($config){
	 *			$config->set('HTML.Allowed', "");
	 *		}
	 *		);
	 * @param string $postVar If you wish to get a specific key, do this!
	 * @param callback $closure You can define a closure with argument $config, The variable is a HTMLPurifier_Config object. See HTMLPurifier Configuration Documentation.
	 * @return gnomephp\input\DataField Returns eiether array or gnomephp\input\DataField depending on what type of field it is.
	 */
	public function get($postVar=null, $closure=null){
		
		// Caching .. 
		if ($postVar === null && $this->fullpostCheck==true){
			return $this->data;
		}elseif($postVar !== null && isset($this->data[$postVar])){
			return $this->data[$postVar];
		}
		
		// Allow configuration!
		if (is_callable($closure)){
			$config = \HTMLPurifier_Config::createDefault();
			$closure($config);
		}else{
			$config = $this->purifierConfig;
		}

		
		if ($postVar){
			$val = isset($this->sourceData[$postVar]) ? $this->sourceData[$postVar] : null;
		}else{
			$val = $this->sourceData;
			$this->fullpostCheck=true;
		}
		if (is_array($val)){
			if ($postVar){
				$this->data[$postVar] = $this->filterPost($val, $config, $postVar);
				return $this->data[$postVar];
			}else{
				$this->data = $this->filterPost($val, $config);
				return $this->data;
			}
		}else{
			$this->data[$postVar] = $this->filterPost($val, $config, $postVar);
			return $this->data[$postVar];
		}
	}

	/**
	 * Refreshes the variable cache of filtered post data.
	 * Useful if you want to recatch $_POST with different HTMLPurifier rules and you have already used get() method.
	 */
	public function refresh(){
		$this->data = array();
	}
	
	/**
	 * 
	 * Filters array of post data.
	 * @param mixed $postVars Post Vars / Post Var.
	 * @param HTMLPurifier_Config $config Configuration.
	 */
	private function filterPost($postVars, $config, $key=null){
		
		if (is_array($postVars)){
			foreach($postVars as $k => $v){
				$postVars[$k] = $this->filterPost($v, $config, $k);
			}
		}else{
			$postVars = new DataField(self::$purifier->purify($postVars, $config), $key);
		}
		
		return $postVars;
	}


}